package com.tnovoselec.android.ui;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.util.AttributeSet;
import android.view.View;

import com.tnovoselec.android.ui.MyViewPager.OnPagerAdapterChangedListener;

public class MyViewPagerIndicator extends View implements OnPageChangeListener, OnPagerAdapterChangedListener {

    private final static int DEFAULT_INDICATOR_SIZE = 5;

    private PagerAdapter mAdapter;
    private MyViewPager nthViewPager;
    private int nthViewPagerId;
    private int indicatorDrawableId;
    private int indicatorDrawableSelectedId;
    private int spaceBetweenIndicators;
    private boolean hideIfSingle;

    private Bitmap indicatorBitmap;
    private Bitmap indicatorBitmapSelected;

    private int current;
    private int count;

    public MyViewPagerIndicator(Context context) {
	this(context, null);
    }

    public MyViewPagerIndicator(Context context, AttributeSet attrs) {
	this(context, attrs, 0);
    }

    public MyViewPagerIndicator(Context context, AttributeSet attrs, int defStyle) {
	super(context, attrs, defStyle);

	try {
	    final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MyViewPagerIndicator, defStyle, 0);
	    nthViewPagerId = a.getResourceId(R.styleable.MyViewPagerTab2_myViewPagerId, View.NO_ID);
	    indicatorDrawableId = a.getResourceId(R.styleable.MyViewPagerIndicator_indicatorDrawable, R.drawable.my_view_pager_indicator);
	    indicatorDrawableSelectedId = a.getResourceId(R.styleable.MyViewPagerIndicator_indicatorDrawableSelected, R.drawable.my_view_pager_indicator_selected);
	    spaceBetweenIndicators = a.getDimensionPixelSize(R.styleable.MyViewPagerIndicator_spaceBetweenIndicators, DEFAULT_INDICATOR_SIZE);
	    hideIfSingle = a.getBoolean(R.styleable.MyViewPagerIndicator_hideIfSingle, true);
	    a.recycle();
	} catch (Exception e) {
	}

	try {
	    int indicatorWidth = -1;
	    int indicatorHeight = -1;

	    final Drawable indicatorDrawable = getResources().getDrawable(indicatorDrawableId);
	    final Drawable indicatorDrawableSelected = getResources().getDrawable(indicatorDrawableSelectedId);

	    if (indicatorDrawableId != 0) {
		indicatorWidth = indicatorDrawable.getIntrinsicWidth();
		indicatorHeight = indicatorDrawable.getIntrinsicHeight();
	    }
	    if (indicatorWidth == -1 || indicatorHeight == -1) {
		final float density = getResources().getDisplayMetrics().density;
		indicatorWidth = (int) (DEFAULT_INDICATOR_SIZE * density);
		indicatorHeight = (int) (DEFAULT_INDICATOR_SIZE * density);
	    }

	    indicatorBitmap = Bitmap.createBitmap(indicatorWidth, indicatorHeight, Config.ARGB_8888);
	    final Canvas canvas1 = new Canvas(indicatorBitmap);
	    indicatorDrawable.setBounds(0, 0, indicatorWidth, indicatorHeight);
	    indicatorDrawable.draw(canvas1);

	    indicatorBitmapSelected = Bitmap.createBitmap(indicatorWidth, indicatorHeight, Config.ARGB_8888);
	    final Canvas canvas2 = new Canvas(indicatorBitmapSelected);
	    indicatorDrawableSelected.setBounds(0, 0, indicatorWidth, indicatorHeight);
	    indicatorDrawableSelected.draw(canvas2);
	} catch (Exception e) {
	}
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
	setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec));
    }

    private int measureWidth(int measureSpec) {
	int result = 0;
	int specMode = MeasureSpec.getMode(measureSpec);
	int specSize = MeasureSpec.getSize(measureSpec);

	if (specMode == MeasureSpec.EXACTLY) {
	    result = specSize;
	} else {
	    result = count * indicatorBitmap.getWidth() + (count - 1) * spaceBetweenIndicators + getPaddingLeft() + getPaddingRight();
	    if (specMode == MeasureSpec.AT_MOST) {
		result = Math.min(result, specSize);
	    }
	}
	return result;
    }

    private int measureHeight(int measureSpec) {
	int result = 0;
	int specMode = MeasureSpec.getMode(measureSpec);
	int specSize = MeasureSpec.getSize(measureSpec);

	if (specMode == MeasureSpec.EXACTLY) {
	    result = specSize;
	} else {
	    result = indicatorBitmap.getHeight() + getPaddingTop() + getPaddingBottom();
	    if (specMode == MeasureSpec.AT_MOST) {
		result = Math.min(result, specSize);
	    }
	}
	return result;
    }

    @Override
    protected void onDraw(Canvas canvas) {
	super.onDraw(canvas);
	final int w = indicatorBitmap.getWidth();
	for (int i = 0; i < count; i++) {
	    canvas.drawBitmap(i == current ? indicatorBitmapSelected : indicatorBitmap, i * (w + spaceBetweenIndicators) + getPaddingLeft(), getPaddingTop(), null);
	}
    }

    @Override
    protected void onAttachedToWindow() {
	super.onAttachedToWindow();

	if (nthViewPagerId != View.NO_ID) {
	    nthViewPager = (MyViewPager) getRootView().findViewById(nthViewPagerId);
	    setNthViewPager(nthViewPager);
	}
    }

    @Override
    public void onPagerAdapterChanged(MyViewPager viewPager) {
	setAdapter(viewPager.getAdapter());
    }

    @Override
    public void onPageScrollStateChanged(int state) {
    }

    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
    }

    @Override
    public void onPageSelected(int position) {
	current = position;
	invalidate();
    }

    public void setAdapter(PagerAdapter adapter) {
	mAdapter = adapter;
	if (mAdapter != null) {
	    count = mAdapter.getCount();
	} else {
	    count = 0;
	}
	if (hideIfSingle && count <= 1) {
	    setVisibility(View.GONE);
	} else {
	    setVisibility(View.VISIBLE);
	    onPageSelected(nthViewPager.getCurrentItem());
	}
    }

    public void setNthViewPager(MyViewPager viewPager) {
	nthViewPager = viewPager;
	if (nthViewPager != null) {
	    nthViewPager.addOnPageChangeListener(this);
	    nthViewPager.addOnPagerAdapterChangedListeners(this);
	    onPagerAdapterChanged(nthViewPager);
	}
    }

}